package top.zhenganwen.security.core.verifycode.processor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;
import top.zhenganwen.security.core.SecurityConstants;
import top.zhenganwen.security.core.verifycode.generator.VerifyCodeGenerator;
import top.zhenganwen.security.core.verifycode.po.ImageCode;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static top.zhenganwen.security.core.verifycode.constont.VerifyCodeConstant.VERIFY_CODE_Generator_IMPL_SUFFIX;
import static top.zhenganwen.security.core.verifycode.constont.VerifyCodeTypeEnum.IMAGE;

/**
 * @author zhenganwen
 * @date 2019/8/29
 * @desc ImageCodeProcessor
 */
@Component
public class ImageCodeProcessorImpl extends AbstractVerifyCodeProcessor<ImageCode> {

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * Spring高级特性
     * Spring会查找容器中所有{@link VerifyCodeGenerator}的实例并以 key=beanId,value=bean的形式注入到该map中
     */
    @Autowired
    private Map<String, VerifyCodeGenerator> verifyCodeGeneratorMap = new HashMap<>();

    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

    @Override
    public ImageCode generateVerifyCode(ServletWebRequest request) {
        VerifyCodeGenerator<ImageCode> verifyCodeGenerator = verifyCodeGeneratorMap.get(IMAGE.getType() + VERIFY_CODE_Generator_IMPL_SUFFIX);
        return verifyCodeGenerator.generateVerifyCode();
    }

    @Override
    public void save(ServletWebRequest request, ImageCode imageCode) {
        ImageCode ic = new ImageCode(imageCode.getCode(), null, imageCode.getExpireTime());
        sessionStrategy.setAttribute(request, SecurityConstants.IMAGE_CODE_SESSION_KEY, ic);
    }

    @Override
    public void send(ServletWebRequest request, ImageCode imageCode) {
        HttpServletResponse response = request.getResponse();
        try {
            ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
        } catch (IOException e) {
            logger.error("输出图形验证码:{}", e.getMessage());
        }
    }
}
